﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Timers;

namespace Campus {
    class RangedAttack : AttackAbility {
        private float m_range;
        public RangedAttack(BaseEntity owner, Animation animation, TargetTypes targetType, 
            int minDamage, int maxDamage, int attackInterval, float attackRange) 
                : base(MenuIcons.AttackIcon, owner, animation, targetType, minDamage, maxDamage, attackInterval) {
            m_range = attackRange;
            LastAttackTime = 0;
        }
        public RangedAttack(RangedAttack copySource)
            : base(copySource) {
            m_range = copySource.m_range;
        }

        public override Ability Clone() {
            return new RangedAttack(this);
        }

        //protected Vector2 ComputeDestination() {
        //    float targetX, targetY, targetSizeX, targetSizeY;
        //    if (Target is BaseEntity) {
        //        targetX = ((BaseEntity)Target).Position.X;
        //        targetY = ((BaseEntity)Target).Position.Y;
        //        targetSizeX = ((BaseEntity)Target).Size.X;
        //        targetSizeY = ((BaseEntity)Target).Size.Y;
        //    } else if (Target is Vector2) {
        //        targetX = ((Vector2)Target).X;
        //        targetY = ((Vector2)Target).Y;
        //        targetSizeX = 0;
        //        targetSizeY = 0;
        //    } else {
        //        targetX = -1;
        //        targetY = -1;
        //        targetSizeX = -1;
        //        targetSizeY = -1;
        //    }
        //    return new Vector2(targetX + (targetSizeX / 2), targetY + (targetSizeY / 2));
        //}

        public override void Update(GameTime gameTime, bool checkInput, bool updateBoundingBox) {
            if (!IsTargetValid()) {
                IsAbilityDone = true;
                Owner.IsAttacking = false;
                return;
            }

            if (Target is BaseEntity) {
                BaseEntity target = (BaseEntity)Target;
                double distanceX = target.Position.X - Owner.Position.X;
                double distanceY = target.Position.Y - Owner.Position.Y;
                double distanceToTarget = Math.Sqrt(distanceX * distanceX + distanceY * distanceY);
                if (distanceToTarget < m_range) {
                    LastAttackTime += gameTime.ElapsedRealTime.Milliseconds;
                    Owner.IsAttacking = true;

                    var unitOwner = Owner as Unit;
                    if (AttackInterval <= LastAttackTime) 
                    {
                        Vector2 offset = Vector2.Zero;
                        bool shouldRestart = true;

                        if (unitOwner != null)
                        {
                            if (unitOwner.CurrentState == Unit.UnitState.AttackLeft)
                            {
                                offset = unitOwner.LeftProjectileOffset;
                            }
                            else if (unitOwner.CurrentState == Unit.UnitState.AttackRight)
                            {
                                offset = unitOwner.RightProjectileOffset;
                            }
                            else if (unitOwner.CurrentState == Unit.UnitState.Die)
                            {
                                shouldRestart = false;
                            }
                        }

                        Projectile proj = new Projectile(target, Owner.Position + offset, AbilityAnimation, 
                            this, MinimumDamage, MaximumDamage);

                        if (Owner.CurrentAnimation != null && !Owner.CurrentAnimation.WillLoop && shouldRestart)
                        {
                            Owner.CurrentAnimation.ResetAnimation();
                            Owner.CurrentAnimation.Start();
                        }

                        LastAttackTime = 0;
                    }
                } else {
                    //move to the target if it is out of range
                    if (Owner is Unit) {
                        Unit unit = (Unit)Owner;
                        MoveAbility move = (MoveAbility)unit.GetMoveAbility().Clone();
                        move.FinalDestination = ((BaseEntity)Target).Position;
                        move.StopDelegate = delegate() {
                            double distX = ((BaseEntity)Target).Position.X - Owner.Position.X;
                            double distY = ((BaseEntity)Target).Position.Y - Owner.Position.Y;
                            double distToTarget = Math.Sqrt(distX * distX + distY * distY);
                            return distToTarget < m_range;
                        };
                        unit.FrontQueueAbility(move);
                        unit.IsAttacking = false;
                    } else {
                        //structure so do nothing
                        Target = null;
                    }

                }
            }
        }
    }
}
